/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#ifndef PLPAGE_FAULT_HANDLER_H
#define PLPAGE_FAULT_HANDLER_H

#include <machine/pc/processor/interrupthandler.h>
#include <tools/PLFlags.h>
using namespace PLSDK;

/**
 * Handles page fault interrupts if they are interrupts for a swap action.
 */
class PageFaultHandler : public InterruptHandler {
public:
	/**
	 * The error flags that can set in the error register if a page fault was
	 * called.<br>
	 * The CR2 register contains the 32-bit linear address that caused the fault.
	 */
	enum PageFaultErrorFlags {
		/**
		 * When set, the fault was caused by a protection violation.
		 * When not set, it was caused by a non-present page.
		 */
		ProtectionViolation			= 1 << 0,
		/**
		 * When set, write access caused the fault; otherwise read access.
		 */
		WriteAccessError				= 1 << 1,
		/**
		 * When set, the fault occurred in user mode; otherwise in supervisor mode.
		 */
		UserMode							= 1 << 2,
		/**
		 * When set, one or more page directory entries contain reserved bits which are set to 1.
		 * This only applies when the PSE or PAE flags in CR4 are set to 1.
		 */
		ReservedBits					= 1 << 3,
		/**
		 * When set, the fault was caused by an instruction fetch.
		 * This only applies when the No-Execute bit is supported and enabled.
		 */
		InstructionFetch				= 1 << 4
	};
	PLDECLAREFLAGS(PageFaultError, PageFaultErrorFlags);
public:
	/**
	 * Constructor.
	 */
	PageFaultHandler();
private:
	/**
	 * Was called if a page fault was called.
	 *
	 * @param nInterruptNumber The interrupt number in this file only 14.
	 * @param state The state of the interrupt registers.
	 * @return True if we can handle this interrupt.
	 */
	bool interrupt(size_t nInterruptNumber, InterruptState &state);
};

#endif
